#include <stdexcept>

#include "instructions/instruction_factory.h"
#include "util/log.hpp"


namespace jvm {
namespace instructions {

// 初始化所有单例指令
const NOP InstructionFactory::nop;
const ACONST_NULL InstructionFactory::aconst_null;
const ICONST_M1 InstructionFactory::iconst_m1;
const ICONST_0 InstructionFactory::iconst_0;
const ICONST_1 InstructionFactory::iconst_1;
const ICONST_2 InstructionFactory::iconst_2;
const ICONST_3 InstructionFactory::iconst_3;
const ICONST_4 InstructionFactory::iconst_4;
const ICONST_5 InstructionFactory::iconst_5;
const LCONST_0 InstructionFactory::lconst_0;
const LCONST_1 InstructionFactory::lconst_1;
const FCONST_0 InstructionFactory::fconst_0;
const FCONST_1 InstructionFactory::fconst_1;
const FCONST_2 InstructionFactory::fconst_2;
const DCONST_0 InstructionFactory::dconst_0;
const DCONST_1 InstructionFactory::dconst_1;

// 加载指令初始化
const ILOAD_0 InstructionFactory::iload_0;
const ILOAD_1 InstructionFactory::iload_1;
const ILOAD_2 InstructionFactory::iload_2;
const ILOAD_3 InstructionFactory::iload_3;
const LLOAD_0 InstructionFactory::lload_0;
const LLOAD_1 InstructionFactory::lload_1;
const LLOAD_2 InstructionFactory::lload_2;
const LLOAD_3 InstructionFactory::lload_3;
const FLOAD_0 InstructionFactory::fload_0;
const FLOAD_1 InstructionFactory::fload_1;
const FLOAD_2 InstructionFactory::fload_2;
const FLOAD_3 InstructionFactory::fload_3;
const DLOAD_0 InstructionFactory::dload_0;
const DLOAD_1 InstructionFactory::dload_1;
const DLOAD_2 InstructionFactory::dload_2;
const DLOAD_3 InstructionFactory::dload_3;
const ALOAD_0 InstructionFactory::aload_0;
const ALOAD_1 InstructionFactory::aload_1;
const ALOAD_2 InstructionFactory::aload_2;
const ALOAD_3 InstructionFactory::aload_3;
const AALOAD InstructionFactory::aaload;
const BALOAD InstructionFactory::baload;
const CALOAD InstructionFactory::caload;
const DALOAD InstructionFactory::daload;
const FALOAD InstructionFactory::faload;
const IALOAD InstructionFactory::iaload;
const LALOAD InstructionFactory::laload;
const SALOAD InstructionFactory::saload;

// 存储指令初始化
const ISTORE_0 InstructionFactory::istore_0;
const ISTORE_1 InstructionFactory::istore_1;
const ISTORE_2 InstructionFactory::istore_2;
const ISTORE_3 InstructionFactory::istore_3;
const LSTORE_0 InstructionFactory::lstore_0;
const LSTORE_1 InstructionFactory::lstore_1;
const LSTORE_2 InstructionFactory::lstore_2;
const LSTORE_3 InstructionFactory::lstore_3;
const FSTORE_0 InstructionFactory::fstore_0;
const FSTORE_1 InstructionFactory::fstore_1;
const FSTORE_2 InstructionFactory::fstore_2;
const FSTORE_3 InstructionFactory::fstore_3;
const DSTORE_0 InstructionFactory::dstore_0;
const DSTORE_1 InstructionFactory::dstore_1;
const DSTORE_2 InstructionFactory::dstore_2;
const DSTORE_3 InstructionFactory::dstore_3;
const ASTORE_0 InstructionFactory::astore_0;
const ASTORE_1 InstructionFactory::astore_1;
const ASTORE_2 InstructionFactory::astore_2;
const ASTORE_3 InstructionFactory::astore_3;
const AASTORE InstructionFactory::aastore;
const BASTORE InstructionFactory::bastore;
const CASTORE InstructionFactory::castore;
const DASTORE InstructionFactory::dastore;
const FASTORE InstructionFactory::fastore;
const IASTORE InstructionFactory::iastore;
const LASTORE InstructionFactory::lastore;
const SASTORE InstructionFactory::sastore;

// 栈操作指令初始化
const POP InstructionFactory::pop;
const POP2 InstructionFactory::pop2;
const DUP InstructionFactory::dup;
const DUP_X1 InstructionFactory::dup_x1;
const DUP_X2 InstructionFactory::dup_x2;
const DUP2 InstructionFactory::dup2;
const DUP2_X1 InstructionFactory::dup2_x1;
const DUP2_X2 InstructionFactory::dup2_x2;
const SWAP InstructionFactory::swap;

// 数学运算指令初始化
const IADD InstructionFactory::iadd;
const LADD InstructionFactory::ladd;
const FADD InstructionFactory::fadd;
const DADD InstructionFactory::dadd;
const ISUB InstructionFactory::isub;
const LSUB InstructionFactory::lsub;
const FSUB InstructionFactory::fsub;
const DSUB InstructionFactory::dsub;
const IMUL InstructionFactory::imul;
const LMUL InstructionFactory::lmul;
const FMUL InstructionFactory::fmul;
const DMUL InstructionFactory::dmul;
const IDIV InstructionFactory::idiv;
const LDIV InstructionFactory::ldiv;
const FDIV InstructionFactory::fdiv;
const DDIV InstructionFactory::ddiv;
const IREM InstructionFactory::irem;
const LREM InstructionFactory::lrem;
const FREM InstructionFactory::frem;
const DREM InstructionFactory::drem;
const INEG InstructionFactory::ineg;
const LNEG InstructionFactory::lneg;
const FNEG InstructionFactory::fneg;
const DNEG InstructionFactory::dneg;

// 位运算指令初始化
const ISHL InstructionFactory::ishl;
const LSHL InstructionFactory::lshl;
const ISHR InstructionFactory::ishr;
const LSHR InstructionFactory::lshr;
const IUSHR InstructionFactory::iushr;
const LUSHR InstructionFactory::lushr;
const IAND InstructionFactory::iand;
const LAND InstructionFactory::land;
const IOR InstructionFactory::ior;
const LOR InstructionFactory::lor;
const IXOR InstructionFactory::ixor;
const LXOR InstructionFactory::lxor;

// 类型转换指令初始化
const I2L InstructionFactory::i2l;
const I2F InstructionFactory::i2f;
const I2D InstructionFactory::i2d;
const L2I InstructionFactory::l2i;
const L2F InstructionFactory::l2f;
const L2D InstructionFactory::l2d;
const F2I InstructionFactory::f2i;
const F2L InstructionFactory::f2l;
const F2D InstructionFactory::f2d;
const D2I InstructionFactory::d2i;
const D2L InstructionFactory::d2l;
const D2F InstructionFactory::d2f;
const I2B InstructionFactory::i2b;
const I2C InstructionFactory::i2c;
const I2S InstructionFactory::i2s;

// 比较指令初始化
const LCMP InstructionFactory::lcmp;
const FCMPL InstructionFactory::fcmpl;
const FCMPG InstructionFactory::fcmpg;
const DCMPL InstructionFactory::dcmpl;
const DCMPG InstructionFactory::dcmpg;

// 返回指令初始化
const RETURN InstructionFactory::_return;
const IRETURN InstructionFactory::ireturn;
const LRETURN InstructionFactory::lreturn;
const DRETURN InstructionFactory::dreturn;
const FRETURN InstructionFactory::freturn;
const ARETURN InstructionFactory::areturn;
const ARRAY_LENGTH InstructionFactory::arraylength;

const ATHROW InstructionFactory::athrow;

const INVOKE_NATIVE InstructionFactory::invoke_native;



InstructionPtr InstructionFactory::newInstruction(uint8_t opcode) {
    switch (opcode) {
        // 常量指令
        case 0x00: return const_cast<NOP*>(&nop);
        case 0x01: return const_cast<ACONST_NULL*>(&aconst_null);
        case 0x02: return const_cast<ICONST_M1*>(&iconst_m1);
        case 0x03: return const_cast<ICONST_0*>(&iconst_0);
        case 0x04: return const_cast<ICONST_1*>(&iconst_1);
        case 0x05: return const_cast<ICONST_2*>(&iconst_2);
        case 0x06: return const_cast<ICONST_3*>(&iconst_3);
        case 0x07: return const_cast<ICONST_4*>(&iconst_4);
        case 0x08: return const_cast<ICONST_5*>(&iconst_5);
        case 0x09: return const_cast<LCONST_0*>(&lconst_0);
        case 0x0a: return const_cast<LCONST_1*>(&lconst_1);
        case 0x0b: return const_cast<FCONST_0*>(&fconst_0);
        case 0x0c: return const_cast<FCONST_1*>(&fconst_1);
        case 0x0d: return const_cast<FCONST_2*>(&fconst_2);
        case 0x0e: return const_cast<DCONST_0*>(&dconst_0);
        case 0x0f: return const_cast<DCONST_1*>(&dconst_1);
        
        // 加载指令
        case 0x10: return std::make_shared<BIPUSH>();
        case 0x11: return std::make_shared<SIPUSH>();
        case 0x12: return std::make_shared<Ldc>();
        case 0x13: return std::make_shared<LdcW>();
        case 0x14: return std::make_shared<Ldc2W>();
        case 0x15: return std::make_shared<ILOAD>();
        case 0x16: return std::make_shared<LLOAD>();
        case 0x17: return std::make_shared<FLOAD>();
        case 0x18: return std::make_shared<DLOAD>();
        case 0x19: return std::make_shared<ALOAD>();
        case 0x1a: return const_cast<ILOAD_0*>(&iload_0);
        case 0x1b: return const_cast<ILOAD_1*>(&iload_1);
        case 0x1c: return const_cast<ILOAD_2*>(&iload_2);
        case 0x1d: return const_cast<ILOAD_3*>(&iload_3);
        case 0x1e: return const_cast<LLOAD_0*>(&lload_0);
        case 0x1f: return const_cast<LLOAD_1*>(&lload_1);
        case 0x20: return const_cast<LLOAD_2*>(&lload_2);
        case 0x21: return const_cast<LLOAD_3*>(&lload_3);
        case 0x22: return const_cast<FLOAD_0*>(&fload_0);
        case 0x23: return const_cast<FLOAD_1*>(&fload_1);
        case 0x24: return const_cast<FLOAD_2*>(&fload_2);
        case 0x25: return const_cast<FLOAD_3*>(&fload_3);
        case 0x26: return const_cast<DLOAD_0*>(&dload_0);
        case 0x27: return const_cast<DLOAD_1*>(&dload_1);
        case 0x28: return const_cast<DLOAD_2*>(&dload_2);
        case 0x29: return const_cast<DLOAD_3*>(&dload_3);
        case 0x2a: return const_cast<ALOAD_0*>(&aload_0);
        case 0x2b: return const_cast<ALOAD_1*>(&aload_1);
        case 0x2c: return const_cast<ALOAD_2*>(&aload_2);
        case 0x2d: return const_cast<ALOAD_3*>(&aload_3);
        case 0x2e: return const_cast<IALOAD*>(&iaload);
        case 0x2f: return const_cast<LALOAD*>(&laload);
        case 0x30: return const_cast<FALOAD*>(&faload);
        case 0x31: return const_cast<DALOAD*>(&daload);
        case 0x32: return const_cast<AALOAD*>(&aaload);
        case 0x33: return const_cast<BALOAD*>(&baload);
        case 0x34: return const_cast<CALOAD*>(&caload);
        case 0x35: return const_cast<SALOAD*>(&saload);
        
        // 存储指令
        case 0x36: return std::make_shared<ISTORE>();
        case 0x37: return std::make_shared<LSTORE>();
        case 0x38: return std::make_shared<FSTORE>();
        case 0x39: return std::make_shared<DSTORE>();
        case 0x3a: return std::make_shared<ASTORE>();
        case 0x3b: return const_cast<ISTORE_0*>(&istore_0);
        case 0x3c: return const_cast<ISTORE_1*>(&istore_1);
        case 0x3d: return const_cast<ISTORE_2*>(&istore_2);
        case 0x3e: return const_cast<ISTORE_3*>(&istore_3);
        case 0x3f: return const_cast<LSTORE_0*>(&lstore_0);
        case 0x40: return const_cast<LSTORE_1*>(&lstore_1);
        case 0x41: return const_cast<LSTORE_2*>(&lstore_2);
        case 0x42: return const_cast<LSTORE_3*>(&lstore_3);
        case 0x43: return const_cast<FSTORE_0*>(&fstore_0);
        case 0x44: return const_cast<FSTORE_1*>(&fstore_1);
        case 0x45: return const_cast<FSTORE_2*>(&fstore_2);
        case 0x46: return const_cast<FSTORE_3*>(&fstore_3);
        case 0x47: return const_cast<DSTORE_0*>(&dstore_0);
        case 0x48: return const_cast<DSTORE_1*>(&dstore_1);
        case 0x49: return const_cast<DSTORE_2*>(&dstore_2);
        case 0x4a: return const_cast<DSTORE_3*>(&dstore_3);
        case 0x4b: return const_cast<ASTORE_0*>(&astore_0);
        case 0x4c: return const_cast<ASTORE_1*>(&astore_1);
        case 0x4d: return const_cast<ASTORE_2*>(&astore_2);
        case 0x4e: return const_cast<ASTORE_3*>(&astore_3);
        case 0x4f: return const_cast<IASTORE*>(&iastore);
        case 0x50: return const_cast<LASTORE*>(&lastore);
        case 0x51: return const_cast<FASTORE*>(&fastore);
        case 0x52: return const_cast<DASTORE*>(&dastore);
        case 0x53: return const_cast<AASTORE*>(&aastore);
        case 0x54: return const_cast<BASTORE*>(&bastore);
        case 0x55: return const_cast<CASTORE*>(&castore);
        case 0x56: return const_cast<SASTORE*>(&sastore);
        
        // 栈操作指令
        case 0x57: return const_cast<POP*>(&pop);
        case 0x58: return const_cast<POP2*>(&pop2);
        case 0x59: return const_cast<DUP*>(&dup);
        case 0x5a: return const_cast<DUP_X1*>(&dup_x1);
        case 0x5b: return const_cast<DUP_X2*>(&dup_x2);
        case 0x5c: return const_cast<DUP2*>(&dup2);
        case 0x5d: return const_cast<DUP2_X1*>(&dup2_x1);
        case 0x5e: return const_cast<DUP2_X2*>(&dup2_x2);
        case 0x5f: return const_cast<SWAP*>(&swap);
        
        // 数学运算指令
        case 0x60: return const_cast<IADD*>(&iadd);
        case 0x61: return const_cast<LADD*>(&ladd);
        case 0x62: return const_cast<FADD*>(&fadd);
        case 0x63: return const_cast<DADD*>(&dadd);
        case 0x64: return const_cast<ISUB*>(&isub);
        case 0x65: return const_cast<LSUB*>(&lsub);
        case 0x66: return const_cast<FSUB*>(&fsub);
        case 0x67: return const_cast<DSUB*>(&dsub);
        case 0x68: return const_cast<IMUL*>(&imul);
        case 0x69: return const_cast<LMUL*>(&lmul);
        case 0x6a: return const_cast<FMUL*>(&fmul);
        case 0x6b: return const_cast<DMUL*>(&dmul);
        case 0x6c: return const_cast<IDIV*>(&idiv);
        case 0x6d: return const_cast<LDIV*>(&ldiv);
        case 0x6e: return const_cast<FDIV*>(&fdiv);
        case 0x6f: return const_cast<DDIV*>(&ddiv);
        case 0x70: return const_cast<IREM*>(&irem);
        case 0x71: return const_cast<LREM*>(&lrem);
        case 0x72: return const_cast<FREM*>(&frem);
        case 0x73: return const_cast<DREM*>(&drem);
        case 0x74: return const_cast<INEG*>(&ineg);
        case 0x75: return const_cast<LNEG*>(&lneg);
        case 0x76: return const_cast<FNEG*>(&fneg);
        case 0x77: return const_cast<DNEG*>(&dneg);
        
        // 位运算指令
        case 0x78: return const_cast<ISHL*>(&ishl);
        case 0x79: return const_cast<LSHL*>(&lshl);
        case 0x7a: return const_cast<ISHR*>(&ishr);
        case 0x7b: return const_cast<LSHR*>(&lshr);
        case 0x7c: return const_cast<IUSHR*>(&iushr);
        case 0x7d: return const_cast<LUSHR*>(&lushr);
        case 0x7e: return const_cast<IAND*>(&iand);
        case 0x7f: return const_cast<LAND*>(&land);
        case 0x80: return const_cast<IOR*>(&ior);
        case 0x81: return const_cast<LOR*>(&lor);
        case 0x82: return const_cast<IXOR*>(&ixor);
        case 0x83: return const_cast<LXOR*>(&lxor);
        
        // 类型转换指令
        case 0x84: return std::make_shared<IINC>();
        case 0x85: return const_cast<I2L*>(&i2l);
        case 0x86: return const_cast<I2F*>(&i2f);
        case 0x87: return const_cast<I2D*>(&i2d);
        case 0x88: return const_cast<L2I*>(&l2i);
        case 0x89: return const_cast<L2F*>(&l2f);
        case 0x8a: return const_cast<L2D*>(&l2d);
        case 0x8b: return const_cast<F2I*>(&f2i);
        case 0x8c: return const_cast<F2L*>(&f2l);
        case 0x8d: return const_cast<F2D*>(&f2d);
        case 0x8e: return const_cast<D2I*>(&d2i);
        case 0x8f: return const_cast<D2L*>(&d2l);
        case 0x90: return const_cast<D2F*>(&d2f);
        case 0x91: return const_cast<I2B*>(&i2b);
        case 0x92: return const_cast<I2C*>(&i2c);
        case 0x93: return const_cast<I2S*>(&i2s);
        
        // 比较指令
        case 0x94: return const_cast<LCMP*>(&lcmp);
        case 0x95: return const_cast<FCMPL*>(&fcmpl);
        case 0x96: return const_cast<FCMPG*>(&fcmpg);
        case 0x97: return const_cast<DCMPL*>(&dcmpl);
        case 0x98: return const_cast<DCMPG*>(&dcmpg);
        
        // 控制指令
        case 0x99: return std::make_shared<IFEQ>();
        case 0x9a: return std::make_shared<IFNE>();
        case 0x9b: return std::make_shared<IFLT>();
        case 0x9c: return std::make_shared<IFGE>();
        case 0x9d: return std::make_shared<IFGT>();
        case 0x9e: return std::make_shared<IFLE>();
        case 0x9f: return std::make_shared<IF_ICMPEQ>();
        case 0xa0: return std::make_shared<IF_ICMPNE>();
        case 0xa1: return std::make_shared<IF_ICMPLT>();
        case 0xa2: return std::make_shared<IF_ICMPGE>();
        case 0xa3: return std::make_shared<IF_ICMPGT>();
        case 0xa4: return std::make_shared<IF_ICMPLE>();
        case 0xa5: return std::make_shared<IF_ACMPEQ>();
        case 0xa6: return std::make_shared<IF_ACMPNE>();
        case 0xa7: return std::make_shared<GOTO>();
        case 0xaa: return std::make_shared<TABLE_SWITCH>();
        case 0xab: return std::make_shared<LOOKUP_SWITCH>();
        case 0xac: return const_cast<IRETURN*>(&ireturn);
        case 0xad: return const_cast<LRETURN*>(&lreturn);
        case 0xae: return const_cast<FRETURN*>(&freturn);
        case 0xaf: return const_cast<DRETURN*>(&dreturn);
        case 0xb0: return const_cast<ARETURN*>(&areturn);
        case 0xb1: return const_cast<RETURN*>(&_return);

        case 0xb2: return std::make_shared<GetStatic>();
        case 0xb3: return std::make_shared<PutStatic>();
        case 0xb4: return std::make_shared<GetField>();
        case 0xb5: return std::make_shared<PutField>();
        case 0xb6: return std::make_shared<InvokeVirtual>();
        case 0xb7: return std::make_shared<InvokeSpecial>();
        case 0xb8: return std::make_shared<INVOKE_STATIC>();
        case 0xb9: return std::make_shared<INVOKE_INTERFACE>();
        case 0xbb: return std::make_shared<New>();
        case 0xbc: return std::make_shared<NEW_ARRAY>();
        case 0xbd: return std::make_shared<ANEW_ARRAY>();
        case 0xbe: return const_cast<ARRAY_LENGTH*>(&arraylength);
        case 0xbf: return const_cast<ATHROW*>(&athrow);

        
        // 扩展指令
        case 0xc0: return std::make_shared<CheckCast>();
        case 0xc1: return std::make_shared<InstanceOf>();
        case 0xc4: return std::make_shared<WIDE>();
        case 0xc5: return std::make_shared<MULTI_ANEW_ARRAY>();
        case 0xc6: return std::make_shared<IFNULL>();
        case 0xc7: return std::make_shared<IFNONNULL>();
        case 0xc8: return std::make_shared<GOTO_W>();

        case 0xfe:return const_cast<INVOKE_NATIVE*>(&invoke_native);
        
        default: {
            // std::ostringstream oss;
            // oss << "Unsupported opcode: 0x" << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(opcode);
            LOG_ERROR("Unsupported opcode: 0x" << (uint32_t)opcode);
            throw std::runtime_error("Unsupported opcode" + std::to_string(opcode));
        }
    }
}

} // namespace instructions
} // namespace jvm